/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package eao.impl;

import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.persistence.EntityManager;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

/**
 *
 * @author dingnangen
 */
public abstract class AbstractFacade<T> {

    private Class<T> entityClass;

    public AbstractFacade(Class<T> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public void create(T entity) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(entity);
        if (constraintViolations.size() > 0) {
            Iterator<ConstraintViolation<T>> iterator = constraintViolations.iterator();
            while (iterator.hasNext()) {
                ConstraintViolation<T> cv = iterator.next();
                System.err.println("Validation" + cv.getRootBeanClass().getName() + "." + cv.getPropertyPath() + " " + cv.getMessage());

//            JsfUtil.addErrorMessage(cv.getRootBeanClass().getSimpleName()+"."+cv.getPropertyPath() + " " +cv.getMessage());
            }
            getEntityManager().persist(entity);
        } else {
            getEntityManager().persist(entity);
        }
    }

    public T edit(T entity) {
        return getEntityManager().merge(entity);
    }

    public void remove(T entity) {
        getEntityManager().remove(getEntityManager().merge(entity));
    }

    public T find(Object id) {
        T t = getEntityManager().find(entityClass, id);
        getEntityManager().refresh(t);
        System.out.println("find(Object id)" + t);
        return t;
    }

    public T findOneItem(String str, List p) {
        T t = null;
        //System.out.println("getEntityManager().createQuery(str).getSingleResult()"+getEntityManager().createQuery(str).getSingleResult());
        try {

            javax.persistence.Query q = getEntityManager().createQuery(str);

            for (int i = 0; i < p.size(); i++) {

                q.setParameter(i + 1, p.get(i));
            }
            t = (T) q.getSingleResult();
            getEntityManager().refresh(t);
        } catch (Exception e) {
            t = null;
        }

//        if (!getEntityManager().createQuery(str).getResultList().isEmpty()) {
//            t = (T) getEntityManager().createQuery(str).getResultList().get(0);
//        }
        //(T) getEntityManager().createQuery(str).getResultList().get(0);
        return t;
    }

    public List<T> findAll() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        List list = getEntityManager().createQuery(cq).getResultList();

        for (Object s : list) {
            getEntityManager().refresh(s);//刷新实体让页面与数据库保持同步
        }
        return list;
    }

    public List<T> findAll(String str, List p) {
        javax.persistence.Query q = getEntityManager().createQuery(str);

        for (int i = 0; i < p.size(); i++) {

            q.setParameter(i + 1, p.get(i));
        }
        List list = q.getResultList();
        for (Object s : list) {
            getEntityManager().refresh(s);//刷新实体让页面与数据库保持同步
        }
        return list;
    }

    public List<T> findRange(int[] range) {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        cq.select(cq.from(entityClass));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        q.setMaxResults(range[1] - range[0] + 1);
        q.setFirstResult(range[0]);
        return q.getResultList();
    }

    public List<T> findRange(int[] range, String str, List p) {
        javax.persistence.Query q = getEntityManager().createQuery(str);
        q.setMaxResults(range[1] - range[0]);
        q.setFirstResult(range[0]);
        for (int i = 0; i < p.size(); i++) {
            q.setParameter(i + 1, p.get(i));
        }
        List list = q.getResultList();
        for (Object s : list) {
            getEntityManager().refresh(s);//刷新实体让页面与数据库保持同步
        }
        return list;
    }

    public int count() {
        javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery();
        javax.persistence.criteria.Root<T> rt = cq.from(entityClass);
        cq.select(getEntityManager().getCriteriaBuilder().count(rt));
        javax.persistence.Query q = getEntityManager().createQuery(cq);
        return ((Long) q.getSingleResult()).intValue();
    }

    public int count(String str) {
        javax.persistence.Query q = getEntityManager().createQuery(str);
        return ((Long) q.getSingleResult()).intValue();
    }

    public int count(String str, List p) {
        javax.persistence.Query q = getEntityManager().createQuery(str);
        if (p != null) {
            for (int i = 0; i < p.size(); i++) {
                q.setParameter(i + 1, p.get(i));
            }
        }
        return ((Long) q.getSingleResult()).intValue();
    }

    public Object nativeQuery(String sql,List p) {
        javax.persistence.Query query = getEntityManager().createNativeQuery(sql);
        if (p != null) {
            for (int i = 0; i < p.size(); i++) {
                query.setParameter(i + 1, p.get(i));
            }
        }
        return  query.getSingleResult();
    }
;
}
